<?php
namespace Engine;
/**
 * Request handler
 * 
 * @version 0.1
 * @author Sergey Tihonov
 */
class Request
{
    /**
     * Array data obtained
     *
     * @var array
     */
    private $_params = array();
    
    /**
     * Fills an array of parameters
     *
     * @return void
     */
    public function __construct()
    {
        $this->_params['post'] = (!empty($_POST)) ? $_POST : array();
        $this->_params['cookie'] = (!empty($_COOKIE)) ? $_COOKIE : array();
        $this->_params['files'] = (!empty($_FILES)) ? $_FILES : array();
        $this->_params['server'] = $_SERVER;
        
        // check uri
        $uri = (!empty($this->_params['server']['REQUEST_URI'])) ? $this->_params['server']['REQUEST_URI'] : '/';
        $uri = trim($uri, '/');
        $uri = strtolower($uri);
        $uri = strtr($uri, array('%20' => '_'));
        $get = array();
        
        if (!empty($uri)) {
            preg_match('/^([a-zа-я0-9\/\_\-]+)(?:([\?a-z0-9\=\&\_\-\.\,]*))$/', $uri, $uri_parts);
            
            if (empty($uri_parts)) {
                throw new \Exception('Uri path is not valid');
            }
            $uri = trim($uri_parts[1], '/');
            $uri_query = (isset($uri_parts[2])) ? $uri_parts[2] : array();
            
            if (!empty($uri_query)) {
                $uri_query = substr($uri_query, 1);
                $query_segments = explode('&', $uri_query);
                foreach ($query_segments as $segment) {
                    $params = explode('=', $segment);
                    $get[$params[0]] = (isset($params[1])) ? $params[1] : null;
                }
            }
        }
        
        $this->_params['uri'] = $uri;
        $this->_params['get'] = $get;
    }
    
    /**
     * Get uri path
     *
     * @return string
     */
    public function getUri()
    {
        return $this->_params['uri'];
    }
    
    /**
     * Get all parameters from GET
     *
     * @return array
     */
    public function getParams()
    {
        return $this->_params['get'];
    }
    
    /**
     * Set param for get
     * 
     * @param string $key
     * @param mixed $value 
     * @return \Engine\Request
     */
    public function setGetParam($key, $value)
    {
        $key = (string)$key;
        $this->_params['get'][$key] = $value;
        return $this;
    }
    
    /**
     * Set array param for get
     * 
     * @param array $params
     * @return \Engine\Request
     */
    public function setGetParams($params)
    {
        if (is_array($params)) {
            foreach ($params as $key => $value) {
                $this->setGetParam($key, $value);
            }
        }
        return $this;
    }
    
    /**
     * A key parameter for an array GET
     *
     * @return mixed
     */
    public function getParam($key)
    {
        if (!array_key_exists($key, $this->_params['get'])) {
            throw new \Exception('Requested key is not found of array parameters');
        }
        
        return $this->_params['get'][$key];
    }
    
    /**
     * Get all parameters from POST
     *
     * @return array
     */
    public function postParams()
    {
        return $this->_params['post'];
    }
    
    /**
     * A key parameter for an array POST
     *
     * @return mixed
     */
    public function postParam($key)
    {
        if (!array_key_exists($key, $this->_params['post'])) {
            throw new \Exception('Requested key is not found of array parameters');
        }
        
        return $this->_params['post'][$key];
    }
    
    /**
     * Get all parameters from SERVER
     *
     * @return array
     */
    public function serverParams()
    {
        return $this->_params['server'];
    }
    
    /**
     * A key parameter for an array SERVER
     *
     * @return null|string
     */
    public function serverParam($key)
    {
        $result = null;
        if (array_key_exists($key, $this->_params['server'])) {
            $result = $this->_params['server'][$key];
        }
        return $result;
    }
    
    /**
     * Whether is method is a POST request
     * 
     * @return bool
     */
    public function isPost()
    {
        return ($this->serverParam('REQUEST_METHOD') === 'POST');
    }
    
    /**
     * Whether is method is a GET request
     * 
     * @return bool 
     */
    public function isGet()
    {
        return ($this->serverParam('REQUEST_METHOD') === 'GET');
    }
    
    /**
     * Whether is request type is a Ajax
     * 
     * @return bool 
     */
    public function isAjax()
    {
    	return (strtolower($this->serverParam('HTTP_X_REQUESTED_WITH')) === 'xmlhttprequest');
    }
}
